package com.ssy.lingxi.order.entity;

import com.fasterxml.jackson.annotation.JsonManagedReference;

import javax.persistence.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Set;

/**
 * 订单表（核心表）
 *
 * @author 万宁
 * @version 2.0.0
 * @date 2021-07-15
 */
@Entity
@Table(schema = "public", name = "ord_order",
        indexes = {@Index(name = "ord_order_create_time_idx", columnList = "createTime"),
                @Index(name = "ord_order_submit_time_idx", columnList = "submitTime"),
                @Index(name = "ord_order_vendor_member_id_idx", columnList = "vendorMemberId"),
                @Index(name = "ord_order_vendor_role_id_idx", columnList = "vendorRoleId"),
                @Index(name = "ord_order_vendor_member_name_idx", columnList = "vendorMemberName"),
                @Index(name = "ord_order_buyer_member_id_idx", columnList = "buyerMemberId"),
                @Index(name = "ord_order_buyer_role_id_idx", columnList = "buyerRoleId"),
                @Index(name = "ord_order_buyer_user_id_idx", columnList = "buyerUserId"),
                @Index(name = "ord_order_buyer_member_name_idx", columnList = "buyerMemberName"),
                @Index(name = "ord_order_no_idx", columnList = "orderNo"),
                @Index(name = "ord_order_digest_idx", columnList = "digest"),
                @Index(name = "ord_order_type_idx", columnList = "orderType"),
                @Index(name = "ord_order_shop_id_idx", columnList = "shopId"),
                @Index(name = "ord_order_shop_type_idx", columnList = "shopType"),
                @Index(name = "ord_order_has_received_idx", columnList = "hasReceived"),
                @Index(name = "ord_order_has_paid_idx", columnList = "hasPaid"),
                @Index(name = "ord_order_vendor_inner_status_idx", columnList = "vendorInnerStatus"),
                @Index(name = "ord_order_buyer_inner_status_idx", columnList = "buyerInnerStatus"),
                @Index(name = "ord_order_outer_status_idx", columnList = "outerStatus"),
                @Index(name = "ord_order_separate_type_idx", columnList = "separateType"),
                @Index(name = "ord_order_promotion_status_idx", columnList = "promotionStatus")})
public class OrderDO implements Serializable {
    private static final long serialVersionUID = -8273815176779471684L;

    /**
     * 订单Id
     */
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ord_order_seq")
    @SequenceGenerator(sequenceName = "ord_order_seq", name = "ord_order_seq", allocationSize = 1)
    private Long id;

    /**
     * 创建时间（下单时间）
     */
    @Column(columnDefinition = "timestamp")
    private LocalDateTime createTime;

    /**
     * 订单提交时间
     */
    @Column(columnDefinition = "timestamp")
    private LocalDateTime submitTime;

    /**
     * 订单归档时间
     */
    @Column(columnDefinition = "timestamp")
    private LocalDateTime archiveTime;

    /**
     * 订单结束时间
     */
    @Column(columnDefinition = "timestamp")
    private LocalDateTime finishTime;

    /**
     * 订单送货时间（段）
     */
    @Column(columnDefinition = "varchar(30)")
    private String deliverPeriod;

    /**
     * 买方（采购）会员Id
     */
    @Column
    private Long buyerMemberId;

    /**
     * 采购会员角色Id
     */
    @Column
    private Long buyerRoleId;

    /**
     * （创建订单的）采购会员用户Id
     */
    @Column
    private Long buyerUserId;

    /**
     * 采购会员名称
     */
    @Column(columnDefinition = "varchar(200)")
    private String buyerMemberName;

    /**
     * 卖方（供应）会员Id
     */
    @Column
    private Long vendorMemberId;

    /**
     * 卖方（供应）会员角色Id
     */
    @Column
    private Long vendorRoleId;

    /**
     * 卖方（供应）会员名称
     */
    @Column(columnDefinition = "varchar(200)")
    private String vendorMemberName;

    /**
     * 卖方（供应）会员用户Id
     */
    @Column
    private Long vendorUserId;

    /**
     * 供应会员会员Logo、或店铺Logo、或自营商城Logo
     */
    @Column(columnDefinition = "varchar(400)")
    private String vendorLogo;

    /**
     * 卖方（供应）的上级会员Id
     */
    @Column
    private Long supplyMemberId;

    /**
     * 卖方（供应）的上级会员角色Id
     */
    @Column
    private Long supplyRoleId;

    /**
     * 卖方（供应）的上级会员名称
     */
    @Column(columnDefinition = "varchar(200)")
    private String supplyMemberName;

    /**
     * 订单编号
     */
    @Column(columnDefinition = "varchar(20)")
    private String orderNo;

    /**
     * 门店Id
     */
    @Column
    private Long storeId;

    /**
     * 订单来源商城Id
     */
    @Column
    private Long shopId;

    /**
     * 订单来源商城的类型，定义在 ShopTypeEnum 中
     */
    @Column
    private Integer shopType;

    /**
     * 订单来源商城的环境，定义在 ShopEnvironmentEnum 中
     */
    @Column
    private Integer shopEnvironment;

    /**
     * 订单来源商城名称
     */
    @Column(columnDefinition = "varchar(50)")
    private String shopName;

    /**
     * 下单模式，定义在OrderModeEnum中
     */
    @Column
    private Integer orderMode;

    /**
     * 订单类型，定义在OrderTypeEnum中
     */
    @Column
    private Integer orderType;

    /**
     * 订单来源类型，定义在 OrderSourceKindEnum 中
     */
    @Column
    private Integer orderKind;

    /**
     * 报价单Id
     */
    @Column
    private Long quoteId;

    /**
     * 报价单号
     */
    @Column(columnDefinition = "varchar(20)")
    private String quoteNo;

    /**
     * 物流单号
     */
    @Column(columnDefinition = "varchar(20)")
    private String logisticsNo;

    /**
     * 订单摘要
     */
    @Column(columnDefinition = "varchar(100)")
    private String digest;

    /**
     * 订单商品总金额 = 商品单价 * 数量
     */
    @Column(columnDefinition = "numeric")
    private BigDecimal productAmount;

    /**
     * 运费
     */
    @Column(columnDefinition = "numeric")
    private BigDecimal freight;

    /**
     * 税费
     */
    @Column(columnDefinition = "numeric")
    private BigDecimal taxes;

    /**
     * 促销活动减低的金额，正数
     */
    @Column(columnDefinition = "numeric")
    private BigDecimal promotionAmount;

    /**
     * 优惠（券）活动减低的金额，正数
     */
    @Column(columnDefinition = "numeric")
    private BigDecimal couponAmount;

    /**
     * 积分抵扣总金额
     */
    @Column(columnDefinition = "numeric")
    private BigDecimal deductionAmount;

    /**
     * 订单总金额 = 订单商品总金额 + 运费 - 促销活动金额 - 优惠券金额
     */
    @Column(columnDefinition = "numeric")
    private BigDecimal totalAmount;

    /**
     * 已经支付的金额
     */
    @Column(columnDefinition = "numeric")
    private BigDecimal paidAmount;

    /**
     * 是否已经支付过一次，用于判断是否可以取消或中止订单
     */
    @Column
    private Boolean hasPaid;

    /**
     * 订单是否满足退款条件（拼团订单的支付记录只有一条，且是100%付款）
     */
    @Column
    private Boolean canRefund;

    /**
     * 订单是否已经“退款”成功
     */
    @Column
    private Boolean hasRefund;

    /**
     * 是否已经发过一次货，用于判断是否可以取消或中止订单
     */
    @Column
    private Boolean hasDelivered;

    /**
     * 是否已经收过一次货，用于判断是否可以取消或中止订单
     */
    @Column
    private Boolean hasReceived;

    /**
     * 采购商是否已经完成了订单评论
     */
    @Column
    private Boolean buyerCommented;

    /**
     * 供应商是否完成了订单评论
     */
    @Column
    private Boolean vendorCommented;

    /**
     * 是否有自提商品
     */
    @Column
    private Boolean pickUp;

    /**
     * 采购商内部状态，定义在 BuyerInnerStatusEnum 中
     */
    @Column
    private Integer buyerInnerStatus;

    /**
     * 供应商内部状态，定义在 VendorInnerStatusEnum 中
     */
    @Column
    private Integer vendorInnerStatus;

    /**
     * 外部状态，定义在OrderOuterStatusEnum中
     */
    @Column
    private Integer outerStatus;

    /**
     * 合并下单、拆单类型枚举，定义在 OrderSeparateTypeEnum 中
     */
    @Column
    private Integer separateType;

    /**
     * （转单后）上级、下级订单的Id
     */
    @Column
    private Long relationId;

    /**
     * （转单后）关联的订单编码
     */
    @Column(columnDefinition = "varchar(20)")
    private String relationNo;

    /**
     * 订单营销活动状态，定义在 OrderPromotionStatusEnum 中
     */
    @Column
    private Integer promotionStatus;

    /**
     * （拼团订单）拼团Id
     */
    @Column
    private Long groupId;

    /**
     * OrderTransitionStatusEnum.class中定义
     * 转单状态(1:未转单,2:拒接单,3:已转单)
     */
    @Column
    private Integer transitionStatus = 1;

    /**
     * 一对一双向关联合同
     */
    @JsonManagedReference
    @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    @JoinColumn(name = "contract_id", referencedColumnName = "id")
    private OrderContractDO contract;

    /**
     * 一对一双向关联发票信息
     */
    @JsonManagedReference
    @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    @JoinColumn(name = "invoice_id", referencedColumnName = "id")
    private OrderInvoiceDO invoice;

    /**
     * 一对多双向关联订单商品
     */
    @JsonManagedReference
    @OneToMany(mappedBy = "order", cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    private Set<OrderProductDO> products;

    /**
     * 一对一双向关联收货人信息
     */
    @JsonManagedReference
    @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    @JoinColumn(name = "consignee_id", referencedColumnName = "id")
    private OrderConsigneeDO consignee;

    /**
     * 一对一双向关联订单其他要求
     */
    @JsonManagedReference
    @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    @JoinColumn(name = "requirement_id", referencedColumnName = "id")
    private OrderRequirementDO requirement;

    /**
     * 一对多双向关联支付记录
     */
    @JsonManagedReference
    @OneToMany(mappedBy = "order", cascade = {CascadeType.DETACH, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    private Set<OrderPaymentDO> payments;

    /**
     * 一对多双向关联收发货记录
     */
    @JsonManagedReference
    @OneToMany(mappedBy = "order", cascade = {CascadeType.DETACH, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    private Set<OrderDeliveryDO> deliveries;

    /**
     * 一对多双向关联营销活动
     */
    @JsonManagedReference
    @OneToMany(mappedBy = "order", cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    private Set<OrderCouponDO> coupons;

    /**
     * 一对多双向关联积分抵扣
     */
    @JsonManagedReference
    @OneToMany(mappedBy = "order", cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    private Set<OrderDeductionDO> deductions;

    /**
     * 一对一单向关联流程任务
     */
    @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    @JoinColumn(name = "task_id", referencedColumnName = "id")
    private OrderProcessTaskDO task;

    /**
     * 一对多双向关联赠品优惠券
     */
    @JsonManagedReference
    @OneToMany(mappedBy = "order", cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    private Set<OrderGiveCouponDO> giveCoupons;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public LocalDateTime getCreateTime() {
        return createTime;
    }

    public void setCreateTime(LocalDateTime createTime) {
        this.createTime = createTime;
    }

    public LocalDateTime getSubmitTime() {
        return submitTime;
    }

    public void setSubmitTime(LocalDateTime submitTime) {
        this.submitTime = submitTime;
    }

    public LocalDateTime getArchiveTime() {
        return archiveTime;
    }

    public void setArchiveTime(LocalDateTime archiveTime) {
        this.archiveTime = archiveTime;
    }

    public LocalDateTime getFinishTime() {
        return finishTime;
    }

    public void setFinishTime(LocalDateTime finishTime) {
        this.finishTime = finishTime;
    }

    public String getDeliverPeriod() {
        return deliverPeriod;
    }

    public void setDeliverPeriod(String deliverPeriod) {
        this.deliverPeriod = deliverPeriod;
    }

    public Long getBuyerMemberId() {
        return buyerMemberId;
    }

    public void setBuyerMemberId(Long buyerMemberId) {
        this.buyerMemberId = buyerMemberId;
    }

    public Long getBuyerRoleId() {
        return buyerRoleId;
    }

    public void setBuyerRoleId(Long buyerRoleId) {
        this.buyerRoleId = buyerRoleId;
    }

    public Long getBuyerUserId() {
        return buyerUserId;
    }

    public void setBuyerUserId(Long buyerUserId) {
        this.buyerUserId = buyerUserId;
    }

    public String getBuyerMemberName() {
        return buyerMemberName;
    }

    public void setBuyerMemberName(String buyerMemberName) {
        this.buyerMemberName = buyerMemberName;
    }

    public Long getVendorMemberId() {
        return vendorMemberId;
    }

    public void setVendorMemberId(Long vendorMemberId) {
        this.vendorMemberId = vendorMemberId;
    }

    public Long getVendorRoleId() {
        return vendorRoleId;
    }

    public void setVendorRoleId(Long vendorRoleId) {
        this.vendorRoleId = vendorRoleId;
    }

    public Long getVendorUserId() { return vendorUserId; }

    public void setVendorUserId(Long vendorUserId) { this.vendorUserId = vendorUserId; }

    public String getVendorMemberName() {
        return vendorMemberName;
    }

    public void setVendorMemberName(String vendorMemberName) {
        this.vendorMemberName = vendorMemberName;
    }

    public String getVendorLogo() {
        return vendorLogo;
    }

    public void setVendorLogo(String vendorLogo) {
        this.vendorLogo = vendorLogo;
    }

    public Long getSupplyMemberId() {
        return supplyMemberId;
    }

    public void setSupplyMemberId(Long supplyMemberId) {
        this.supplyMemberId = supplyMemberId;
    }

    public Long getSupplyRoleId() {
        return supplyRoleId;
    }

    public void setSupplyRoleId(Long supplyRoleId) {
        this.supplyRoleId = supplyRoleId;
    }

    public String getSupplyMemberName() {
        return supplyMemberName;
    }

    public void setSupplyMemberName(String supplyMemberName) {
        this.supplyMemberName = supplyMemberName;
    }

    public String getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    public Long getStoreId() {
        return storeId;
    }

    public void setStoreId(Long storeId) {
        this.storeId = storeId;
    }

    public Long getShopId() {
        return shopId;
    }

    public void setShopId(Long shopId) {
        this.shopId = shopId;
    }

    public Integer getShopType() {
        return shopType;
    }

    public void setShopType(Integer shopType) {
        this.shopType = shopType;
    }

    public Integer getShopEnvironment() {
        return shopEnvironment;
    }

    public void setShopEnvironment(Integer shopEnvironment) {
        this.shopEnvironment = shopEnvironment;
    }

    public String getShopName() {
        return shopName;
    }

    public void setShopName(String shopName) {
        this.shopName = shopName;
    }

    public Integer getOrderMode() {
        return orderMode;
    }

    public void setOrderMode(Integer orderMode) {
        this.orderMode = orderMode;
    }

    public Integer getOrderType() {
        return orderType;
    }

    public void setOrderType(Integer orderType) {
        this.orderType = orderType;
    }

    public Integer getOrderKind() {
        return orderKind;
    }

    public void setOrderKind(Integer orderKind) {
        this.orderKind = orderKind;
    }

    public Long getQuoteId() {
        return quoteId;
    }

    public void setQuoteId(Long quoteId) {
        this.quoteId = quoteId;
    }

    public String getQuoteNo() {
        return quoteNo;
    }

    public void setQuoteNo(String quoteNo) {
        this.quoteNo = quoteNo;
    }

    public String getLogisticsNo() {
        return logisticsNo;
    }

    public void setLogisticsNo(String logisticsNo) {
        this.logisticsNo = logisticsNo;
    }

    public String getDigest() {
        return digest;
    }

    public void setDigest(String digest) {
        this.digest = digest;
    }

    public BigDecimal getProductAmount() {
        return productAmount;
    }

    public void setProductAmount(BigDecimal productAmount) {
        this.productAmount = productAmount;
    }

    public BigDecimal getFreight() {
        return freight;
    }

    public void setFreight(BigDecimal freight) {
        this.freight = freight;
    }

    public BigDecimal getTaxes() {
        return taxes;
    }

    public void setTaxes(BigDecimal taxes) {
        this.taxes = taxes;
    }

    public BigDecimal getPromotionAmount() {
        return promotionAmount;
    }

    public void setPromotionAmount(BigDecimal promotionAmount) {
        this.promotionAmount = promotionAmount;
    }

    public BigDecimal getCouponAmount() {
        return couponAmount;
    }

    public void setCouponAmount(BigDecimal couponAmount) {
        this.couponAmount = couponAmount;
    }

    public BigDecimal getDeductionAmount() {
        return deductionAmount;
    }

    public void setDeductionAmount(BigDecimal deductionAmount) {
        this.deductionAmount = deductionAmount;
    }

    public BigDecimal getTotalAmount() {
        return totalAmount;
    }

    public void setTotalAmount(BigDecimal totalAmount) {
        this.totalAmount = totalAmount;
    }

    public BigDecimal getPaidAmount() {
        return paidAmount;
    }

    public void setPaidAmount(BigDecimal paidAmount) {
        this.paidAmount = paidAmount;
    }

    public Boolean getHasPaid() {
        return hasPaid;
    }

    public void setHasPaid(Boolean hasPaid) {
        this.hasPaid = hasPaid;
    }

    public Boolean getCanRefund() {
        return canRefund;
    }

    public void setCanRefund(Boolean canRefund) {
        this.canRefund = canRefund;
    }

    public Boolean getHasRefund() {
        return hasRefund;
    }

    public void setHasRefund(Boolean hasRefund) {
        this.hasRefund = hasRefund;
    }

    public Boolean getHasDelivered() {
        return hasDelivered;
    }

    public void setHasDelivered(Boolean hasDelivered) {
        this.hasDelivered = hasDelivered;
    }

    public Boolean getHasReceived() {
        return hasReceived;
    }

    public void setHasReceived(Boolean hasReceived) {
        this.hasReceived = hasReceived;
    }

    public Boolean getBuyerCommented() {
        return buyerCommented;
    }

    public void setBuyerCommented(Boolean buyerCommented) {
        this.buyerCommented = buyerCommented;
    }

    public Boolean getVendorCommented() {
        return vendorCommented;
    }

    public void setVendorCommented(Boolean vendorCommented) {
        this.vendorCommented = vendorCommented;
    }

    public Boolean getPickUp() {
        return pickUp;
    }

    public void setPickUp(Boolean pickUp) {
        this.pickUp = pickUp;
    }

    public Integer getBuyerInnerStatus() {
        return buyerInnerStatus;
    }

    public void setBuyerInnerStatus(Integer buyerInnerStatus) {
        this.buyerInnerStatus = buyerInnerStatus;
    }

    public Integer getVendorInnerStatus() {
        return vendorInnerStatus;
    }

    public void setVendorInnerStatus(Integer vendorInnerStatus) {
        this.vendorInnerStatus = vendorInnerStatus;
    }

    public Integer getOuterStatus() {
        return outerStatus;
    }

    public void setOuterStatus(Integer outerStatus) {
        this.outerStatus = outerStatus;
    }

    public Integer getSeparateType() {
        return separateType;
    }

    public void setSeparateType(Integer separateType) {
        this.separateType = separateType;
    }

    public Long getRelationId() {
        return relationId;
    }

    public void setRelationId(Long relationId) {
        this.relationId = relationId;
    }

    public String getRelationNo() {
        return relationNo;
    }

    public void setRelationNo(String relationNo) {
        this.relationNo = relationNo;
    }

    public Integer getPromotionStatus() {
        return promotionStatus;
    }

    public void setPromotionStatus(Integer promotionStatus) {
        this.promotionStatus = promotionStatus;
    }

    public Long getGroupId() {
        return groupId;
    }

    public void setGroupId(Long groupId) {
        this.groupId = groupId;
    }

    public OrderContractDO getContract() {
        return contract;
    }

    public void setContract(OrderContractDO contract) {
        this.contract = contract;
    }

    public OrderInvoiceDO getInvoice() {
        return invoice;
    }

    public void setInvoice(OrderInvoiceDO invoice) {
        this.invoice = invoice;
    }

    public Set<OrderProductDO> getProducts() {
        return products;
    }

    public void setProducts(Set<OrderProductDO> products) {
        this.products = products;
    }

    public OrderConsigneeDO getConsignee() {
        return consignee;
    }

    public void setConsignee(OrderConsigneeDO consignee) {
        this.consignee = consignee;
    }

    public OrderRequirementDO getRequirement() {
        return requirement;
    }

    public void setRequirement(OrderRequirementDO requirement) {
        this.requirement = requirement;
    }

    public Set<OrderPaymentDO> getPayments() {
        return payments;
    }

    public void setPayments(Set<OrderPaymentDO> payments) {
        this.payments = payments;
    }

    public Set<OrderDeliveryDO> getDeliveries() {
        return deliveries;
    }

    public void setDeliveries(Set<OrderDeliveryDO> deliveries) {
        this.deliveries = deliveries;
    }

    public Set<OrderCouponDO> getCoupons() {
        return coupons;
    }

    public void setCoupons(Set<OrderCouponDO> coupons) {
        this.coupons = coupons;
    }

    public Set<OrderDeductionDO> getDeductions() {
        return deductions;
    }

    public void setDeductions(Set<OrderDeductionDO> deductions) {
        this.deductions = deductions;
    }

    public OrderProcessTaskDO getTask() {
        return task;
    }

    public void setTask(OrderProcessTaskDO task) {
        this.task = task;
    }

    public Integer getTransitionStatus() {
        return transitionStatus;
    }

    public void setTransitionStatus(Integer transitionStatus) {
        this.transitionStatus = transitionStatus;
    }

    public Set<OrderGiveCouponDO> getGiveCoupons() {
        return giveCoupons;
    }

    public void setGiveCoupons(Set<OrderGiveCouponDO> giveCoupons) {
        this.giveCoupons = giveCoupons;
    }

    public OrderDO() {
    }

    public OrderDO(Long id, Long buyerUserId, Long vendorUserId, BigDecimal totalAmount, BigDecimal paidAmount) {
        this.id = id;
        this.buyerUserId = buyerUserId;
        this.vendorUserId = vendorUserId;
        this.totalAmount = totalAmount;
        this.paidAmount = paidAmount;
    }
}
